<template>
  <div class="login-box">
    <div class="system-info">
      <h2 class="system-title">供应链知识图谱系统</h2> <!-- 添加标题 -->
      <div class="demo-graph" ref="demoGraph"></div>
    </div>
    <div class="login-panel">
      <div class="login-content">
        <h2 class="login-title">登 录</h2>
        <el-form
          :model="loginForm"
          :rules="loginRules"
          ref="loginForm"
          label-width="80px"
          class="login-form"
        >
          <el-form-item label="用户名" prop="username">
            <el-input
              v-model="loginForm.username"
              autocomplete="off"
            ></el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input
              type="password"
              v-model="loginForm.password"
              autocomplete="off"
            ></el-input>
          </el-form-item>
          <el-button
            type="primary"
            @click="login()"
            @keyup.enter.native="bindEnter()"
            class="login-btn"
          >
            登录
          </el-button>
          <a @click="gotoRegister()" class="register-btn">
            注 册
          </a>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import { mapActions } from 'vuex'
import * as d3 from 'd3'
import {$message} from "@/common/utils";

const validateUsername = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请输入用户名'))
  } else {
    callback()
  }
}
const validateLoginPassword = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  }
}

export default {
  name: 'Login',
  data() {
    return {
      loginForm: {
        username: '',
        password: ''
      },
      loginRules: {
        username: [{ validator: validateUsername, trigger: 'blur' }],
        password: [{ validator: validateLoginPassword, trigger: 'blur' }]
      },
      demoData: {
        nodes: [
          { id: 1, name: '华为', group: 1, radius: 3 },
          { id: 2, name: '中芯国际', group: 2, radius: 2.5 },
          { id: 3, name: '台积电', group: 2, radius: 2.5 },
          { id: 4, name: '联发科', group: 3, radius: 2 },
          { id: 5, name: '高通', group: 3, radius: 2 },
          { id: 6, name: '芯片制造', group: 4, radius: 1.5 },
          { id: 7, name: '晶圆代工', group: 4, radius: 1.5 },
          { id: 8, name: '手机制造', group: 5, radius: 1.5 },
          { id: 9, name: '基带芯片', group: 5, radius: 1.5 },
          { id: 10, name: '三星', group: 1, radius: 3 },
          { id: 11, name: '苹果', group: 1, radius: 3 },
          { id: 12, name: '英特尔', group: 2, radius: 2.5 },
          { id: 13, name: 'AMD', group: 2, radius: 2.5 },
          { id: 14, name: '博通', group: 3, radius: 2 },
          { id: 15, name: '英伟达', group: 3, radius: 2 },
          { id: 16, name: '索尼', group: 1, radius: 3 },
          { id: 17, name: '微软', group: 1, radius: 3 },
          { id: 18, name: '高通芯片', group: 4, radius: 1.5 },
          { id: 19, name: '半导体设备', group: 4, radius: 1.5 },
          { id: 20, name: '智能手机', group: 5, radius: 1.5 }
        ],
        links: [
          { source: 1, target: 2, value: 2 },
          { source: 1, target: 3, value: 2 },
          { source: 2, target: 6, value: 1 },
          { source: 3, target: 7, value: 1 },
          { source: 4, target: 1, value: 1 },
          { source: 5, target: 1, value: 1 },
          { source: 4, target: 9, value: 1 },
          { source: 5, target: 9, value: 1 },
          { source: 1, target: 8, value: 1 },
          { source: 10, target: 11, value: 2 },
          { source: 10, target: 12, value: 1 },
          { source: 11, target: 13, value: 1 },
          { source: 12, target: 14, value: 1 },
          { source: 13, target: 15, value: 1 },
          { source: 14, target: 5, value: 1 },
          { source: 15, target: 4, value: 1 },
          { source: 16, target: 17, value: 2 },
          { source: 16, target: 18, value: 1 },
          { source: 17, target: 19, value: 1 },
          { source: 18, target: 20, value: 1 },
          { source: 19, target: 6, value: 1 },
          { source: 20, target: 8, value: 1 },
          // 新增连线
          { source: 1, target: 10, value: 1 },
          { source: 2, target: 11, value: 1 },
          { source: 3, target: 12, value: 1 },
          { source: 4, target: 13, value: 1 },
          { source: 5, target: 14, value: 1 },
          { source: 6, target: 15, value: 1 },
          { source: 7, target: 16, value: 1 },
          { source: 8, target: 17, value: 1 },
          { source: 9, target: 18, value: 1 },
          { source: 10, target: 19, value: 1 },
          { source: 11, target: 20, value: 1 }
        ]
      }
    }
  },
  methods: {
    ...mapActions(['userLogin']),
    login() {
      const userInfo = { ...this.loginForm }
      this.userLogin(userInfo).then(success => {
        console.log(success)
        if (success) {
          this.$router.push('/')
        }
      })
    },
    gotoRegister() {
      this.$router.push('/user/register')
    },
    bindEnter(e) {
      if (e.keyCode === 13) {
        this.login()
      }
    },
    initDemoGraph() {
      const width = this.$refs.demoGraph.clientWidth;
      const height = this.$refs.demoGraph.clientHeight;
      const color = d3.scaleOrdinal(d3.schemeBlues[9]); // 使用蓝色色系调色板

      // 清除已有内容
      d3.select(this.$refs.demoGraph).selectAll("*").remove();

      const svg = d3.select(this.$refs.demoGraph)
        .append('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .attr('viewBox', [0, 0, width, height]);

      const simulation = d3.forceSimulation(this.demoData.nodes)
        .force('link', d3.forceLink(this.demoData.links).id(d => d.id))
        .force('charge', d3.forceManyBody().strength(-300))
        .force('center', d3.forceCenter(width / 2, height / 2))
        .force('collide', d3.forceCollide().radius(d => d.radius * 13 + 5)); // 防止节点重叠

      const link = svg.append('g')
        .selectAll('line')
        .data(this.demoData.links)
        .join('line')
        .attr('stroke', '#add8e6') // 浅蓝色调
        .attr('stroke-opacity', 0.8)
        .attr('stroke-width', d => Math.sqrt(d.value) * 1.5);

      const node = svg.append('g')
        .selectAll('g')
        .data(this.demoData.nodes)
        .join('g');

      node.append('circle')
        .attr('r', d => d.radius * 13)
        .attr('fill', d => color(d.group))
        .attr('stroke', '#fff')
        .attr('stroke-width', 2);

      node.append('text')
        .text(d => d.name)
        .attr('x', 0)
        .attr('y', 0)
        .attr('text-anchor', 'middle')
        .attr('dominant-baseline', 'middle')
        .attr('font-size', '11px')
        .attr('fill', d => d3.color(color(d.group)).darker(2)); // 根据节点颜色调整字体颜色

      node.call(d3.drag()
        .on('start', dragstarted)
        .on('drag', dragged)
        .on('end', dragended));

      simulation.on('tick', () => {
        link
          .attr('x1', d => Math.max(d.source.x, 0))
          .attr('y1', d => Math.max(d.source.y, 0))
          .attr('x2', d => Math.min(d.target.x, width))
          .attr('y2', d => Math.min(d.target.y, height));

        node
          .attr('transform', d => `translate(${Math.max(d.radius * 13, Math.min(width - d.radius * 13, d.x))},${Math.max(d.radius * 13, Math.min(height - d.radius * 13, d.y))})`);
      });

      function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
      }

      function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
      }

      function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
      }
    }
  },
  mounted() {
    this.initDemoGraph();
    document.addEventListener('keydown', this.bindEnter);
  },
  destroyed() {
    document.removeEventListener('keydown', this.bindEnter);
  }
}
</script>

<style scoped>
.login-box {
  display: flex;
  width: 100vw;
  height: 100vh;
  background: linear-gradient(135deg, #e0eafc 0%, #cfdef3 100%);
  font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.system-info {
  position: relative; /* 使子元素可以绝对定位 */
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  color: #ffffff;
  background-image: url('login-bg.jpg');
  background-size: cover;
  background-position: center;
  width: 50%; /* 占据一半宽度 */
}

.system-title {
  position: absolute; /* 绝对定位 */
  top: 130px; /* 距离顶部10px */
  left: 50%; /* 水平居中 */
  transform: translateX(-50%); /* 水平居中调整 */
  font-size: 2rem;
  font-weight: 700;
  color: #ffffff; /* 确保标题颜色与背景对比明显 */
  text-align: center;
}

.demo-graph {
  width: 100%; /* 占据整个system-info */
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
}

.login-panel {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #ffffff;
  width: 50%; /* 占据一半宽度 */
}

.system-title {
  font-size: 2rem;
  font-weight: 700;
  color: #ffffff; /* 确保标题颜色与背景对比明显 */
  text-align: center;
}

.system-subtitle {
  font-size: 1.5rem;
  font-weight: 500;
  margin-bottom: 2rem;
  color: #ecf0f1;
}

.system-description {
  font-size: 1rem;
  line-height: 1.6;
  color: #bdc3c7;
}

.login-content {
  width: 80%;
  max-width: 400px;
}

.login-title {
  font-size: 2rem;
  color: #2c3e50;
  margin-bottom: 2rem;
  text-align: center;
  font-weight: 600;
}

.login-form {
  margin-top: 1rem;
}

.el-input {
  width: 100%;
}

.login-btn {
  width: 100%;
  margin-top: 1rem;
  margin-bottom: 1rem;
  height: 40px;
  font-size: 1rem;
  font-weight: 600;
  background-color: #3498db;
  border-color: #3498db;
}

.login-btn:hover {
  background-color: #2980b9;
  border-color: #2980b9;
}

.register-btn {
  display: block;
  font-size: 0.9rem;
  margin-top: 1rem;
  cursor: pointer;
  color: #3498db;
  text-align: center;
  text-decoration: none;
  transition: color 0.3s ease;
}

.register-btn:hover {
  color: #2980b9;
}

@media (max-width: 768px) {
  .login-box {
    flex-direction: column;
  }

  .system-info {
    padding: 2rem 5%;
  }

  .system-title {
    font-size: 2rem;
  }

  .system-subtitle {
    font-size: 1.2rem;
  }

  .login-panel {
    padding: 2rem 0;
  }
}
</style>
